﻿using System;
using System.Windows.Forms;
using System.IO;
using System.Net;
using Microsoft.Win32;
using CustomerAssistant.Core;
using System.Diagnostics;
using System.Security.Cryptography;

namespace CAssistantUpdateSvc
{
    internal static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        private static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            CheckUpdate();
            Application.Run();
        }

        static void CheckUpdate()
        {
            var msiPath = Application.StartupPath + "\\CustomerAssistantSetup.msi";
            var url = Properties.Settings.Default.serviceUrl;
            var newMD5 = Util.HttpRequest(url, "handle=getmd5");
            var oldMD5 = Util.FileMd5_hash(msiPath);
            if (oldMD5 == null || string.Compare(oldMD5, newMD5, true) != 0)
            {
                //网络更新
                if (DownloadFile(string.Format("{0}?handle=download", url), msiPath))
                    Update(msiPath);
            }
            else
            {
                //本地安装包与网络安装包签名一致,检查正在使用的版本
                oldMD5 = GetRegistData("ItourCustomerAssistant", "Signature");
                if (string.Compare(oldMD5, newMD5, true) != 0)
                    //本地安装包下载后用户取消了更新,现在再尝试提醒用户更新一次
                    Update(msiPath);
            }
        }

        static void Update(string msiPath)
        {
            MessageBox.Show("已从服务器下载最新更新,即将安装更新!", "客户助手", MessageBoxButtons.OK);
            KillProcess("CustomerAssistant");
            Process.Start(new ProcessStartInfo(msiPath));
            Application.Exit();
        }

        static void KillProcess(string procName)
        {
            var list = Process.GetProcessesByName(procName);
            foreach (Process proc in list)
                proc.Kill();
        }

        static string GetRegistData(string name, string subKey)
        {
            try
            {
                string registData;
                RegistryKey hkml = Registry.LocalMachine;
                RegistryKey software = hkml.OpenSubKey("SOFTWARE", true);
                RegistryKey softkey = software.OpenSubKey(subKey, true);
                registData = softkey.GetValue(name).ToString();
                return registData;
            }
            catch
            {
                return null;
            }
        }

        static bool SetRegistData(string name, string subKey, object value)
        {
            try
            {
                RegistryKey hkml = Registry.LocalMachine;
                RegistryKey software = hkml.OpenSubKey("SOFTWARE", true);
                RegistryKey softkey = software.OpenSubKey(subKey, true);
                softkey.SetValue(name, value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool DownloadFile(string url, string localPath)
        {
            bool flag = false;
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                req.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                long totalBytes = resp.ContentLength;
                using (Stream sResp = resp.GetResponseStream())
                {
                    var _path = localPath.Substring(0, localPath.LastIndexOf('\\'));
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    using (Stream sFile = new FileStream(localPath, FileMode.Create))
                    {
                        long totalDownloadBytes = 0;
                        byte[] bs = new byte[1024];
                        for (int size = sResp.Read(bs, 0, bs.Length); size > 0; size = sResp.Read(bs, 0, bs.Length))
                        {
                            totalDownloadBytes += size;
                            sFile.Write(bs, 0, size);
                        }
                        sFile.Flush();
                    }
                }
                flag = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return flag;
        }
    }
}